package com.ybkj.o2o.zhuanche.manager.impl;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ybkj.o2o.zhuanche.amqp.DockingSuperviseApi;
import com.ybkj.o2o.zhuanche.amqp.PushMessage;
import com.ybkj.o2o.zhuanche.amqp.docking.DdcxMessage;
import com.ybkj.o2o.zhuanche.amqp.docking.DdwyMessage;
import com.ybkj.o2o.zhuanche.common.CompanyOrderVo;
import com.ybkj.o2o.zhuanche.common.DataGrid;
import com.ybkj.o2o.zhuanche.common.Distance;
import com.ybkj.o2o.zhuanche.common.DriverOrderDetailVo;
import com.ybkj.o2o.zhuanche.common.DriverOrderVo;
import com.ybkj.o2o.zhuanche.common.MemberOrderVo;
import com.ybkj.o2o.zhuanche.common.OrderFromSourceVo;
import com.ybkj.o2o.zhuanche.common.PageVo;
import com.ybkj.o2o.zhuanche.common.api.DaijiaApi;
import com.ybkj.o2o.zhuanche.common.api.PassengerApi;
import com.ybkj.o2o.zhuanche.common.api.SalesApi;
import com.ybkj.o2o.zhuanche.common.query.OrderQuery;
import com.ybkj.o2o.zhuanche.controller.v4.Error;
import com.ybkj.o2o.zhuanche.controller.v4.ErrorConstantV4;
import com.ybkj.o2o.zhuanche.controller.v4.ResultTransport;
import com.ybkj.o2o.zhuanche.entity.Car;
import com.ybkj.o2o.zhuanche.entity.CarType;
import com.ybkj.o2o.zhuanche.entity.ChartDay;
import com.ybkj.o2o.zhuanche.entity.ChartMonth;
import com.ybkj.o2o.zhuanche.entity.ChartYear;
import com.ybkj.o2o.zhuanche.entity.Order;
import com.ybkj.o2o.zhuanche.entity.OrderGroup;
import com.ybkj.o2o.zhuanche.entity.OrderMemo;
import com.ybkj.o2o.zhuanche.entity.OrderRefuse;
import com.ybkj.o2o.zhuanche.entity.OrderStatus;
import com.ybkj.o2o.zhuanche.entity.ServiceEntity;
import com.ybkj.o2o.zhuanche.entity.ServiceType;
import com.ybkj.o2o.zhuanche.manager.OrderManager;
import com.ybkj.o2o.zhuanche.service.CarService;
import com.ybkj.o2o.zhuanche.service.CarTypeService;
import com.ybkj.o2o.zhuanche.service.ChartService;
import com.ybkj.o2o.zhuanche.service.OrderGroupService;
import com.ybkj.o2o.zhuanche.service.OrderMemoService;
import com.ybkj.o2o.zhuanche.service.OrderRefuseService;
import com.ybkj.o2o.zhuanche.service.OrderService;
import com.ybkj.o2o.zhuanche.service.OrderStatusService;
import com.ybkj.o2o.zhuanche.service.ServiceTypeService;

@Service
public class DefaultOrderManager implements OrderManager {

  @Autowired
  private CarService carService;

  @Autowired
  private OrderService orderService;

  @Autowired
  private CarTypeService carTypeService;


  @Autowired
  private OrderStatusService statusService;

  @Autowired
  private OrderRefuseService refuseService;

  @Autowired
  private OrderMemoService orderMemoService;

  @Autowired
  private ServiceTypeService serviceTypeService;

  @Autowired
  private OrderGroupService orderGroupService;

  @Autowired
  @Qualifier("shopRabbitTemplate")
  private RabbitTemplate rabbitTemplate;


  @Autowired
  private DaijiaApi daijiaApi;

  @Autowired
  private SalesApi salesApi;

  @Autowired
  private ChartService chartService;
  @Autowired
  @Qualifier("dsRabbitTemplate")
  private RabbitTemplate dsRabbitTemplate;

  @Autowired
  private PassengerApi passengerApi;
  
  @Autowired
  private DockingSuperviseApi dockingSuperviseApi;
  
  @Override
  public Order queryOneOrder(Long orderId, String appKey) {
    Order order = orderService.queryOneOrder(orderId, appKey);
    if (order != null) {
      if (StringUtils.isBlank(order.getShowPhone())) {
        order.setShowPhone(order.getPassengerPhone());
      }
      if (order.getAreaId() == null) {
        CarType carType = carTypeService.findByCarTypeId(order.getCarTypeId(), appKey);
        if (carType != null && carType.getAreaId() != null) {
          order.setAreaId(carType.getAreaId());
        } else {
          if (null != order.getServiceTypeId()) {
            ServiceType serviceType =
                serviceTypeService.findByServiceTypeId(order.getServiceTypeId(), appKey);
            if (serviceType != null) {
              order.setAreaId(serviceType.getAreaId());
            }
          }
        }
      }
    }
    return order;
  }

  @Override
  public Order findByIdAndAppKey(Long orderId, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);

    if (order != null) {
      if (StringUtils.isBlank(order.getShowPhone())) {
        order.setShowPhone(order.getPassengerPhone());
      }
      if (order.getAreaId() == null) {
        CarType carType = carTypeService.findByCarTypeId(order.getCarTypeId(), appKey);
        if (carType != null && carType.getAreaId() != null) {
          order.setAreaId(carType.getAreaId());
        } else {
          if (null != order.getServiceTypeId()) {
            ServiceType serviceType =
                serviceTypeService.findByServiceTypeId(order.getServiceTypeId(), appKey);
            if (serviceType != null) {
              order.setAreaId(serviceType.getAreaId());
            }
          }
        }
      }
    }
    return order;
  }

  // APP使用
  @Override
  public Map<String, Object> findByIdAndAppKeyV4up(Long orderId, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>(22);
    Order order = orderService.queryOneOrder(orderId, appKey);
    if (null != order) {
      if (StringUtils.isBlank(order.getShowPhone())) {
        order.setShowPhone(order.getPassengerPhone());
      }
      CarType carType = carTypeService.findByCarTypeId(order.getCarTypeId(), appKey);
      if (null != carType) {
        map.put("carTypeName", carType.getTypeName());
      } else {
        map.put("carTypeName", "");
      }
      map.put("orderId", order.getId());
      map.put("orderNumber", order.getOrderNo());
      map.put("time", order.getServerTime().getTime());
      map.put("status", order.getStatus());
      map.put("orderType", "zhuanche");
      map.put("serviceType", order.getServiceType());
      if (null != order.getServiceType()
          && (order.getServiceType().compareTo(Order.ServiceType.jieji) == 0)
          || order.getServiceType().compareTo(Order.ServiceType.songji) == 0) {
        map.put("flightNo", order.getFlightNo());
      } else if (null != order.getServiceType()
          && (order.getServiceType().compareTo(Order.ServiceType.jiezhan) == 0)
          || order.getServiceType().compareTo(Order.ServiceType.songzhan) == 0) {
        map.put("trainNo", order.getTrainNo());
      }

      map.put("startLng", order.getStartLng());
      map.put("startLat", order.getStartLat());
      map.put("endLng", order.getEndLng());
      map.put("endLat", order.getEndLat());
      map.put("fromPlace", order.getStartAddress());
      map.put("toPlace", order.getEndAddress());
      map.put("passengerPhone", order.getShowPhone());
      map.put("passengerName", order.getPassengerName());
      map.put("companyAbbreviation", order.getCompanyName());
      map.put("memo", order.getMemo());
      map.put("budgetPay", order.getBudgetPay());
      map.put("shouldPay", order.getRealPay());
      map.put("areaId", order.getAreaId());
      map.put("voiceId", order.getVoiceId());
      map.put("voiceHttpPath", order.getVoiceHttpPath());
      map.put("bookStatus", order.getBookStatus());
      map.put("makePrice", order.getMakePrice());//订单定价
      map.put("isMakePrice", order.getIsMakePrice());//是否订单定价 0.否 1.是
      Long countNum=0L;
      Date end=new Date();
      Calendar calendar=Calendar.getInstance();
      calendar.setTime(end);
      calendar.add(Calendar.MONTH, -6);
      Date start = calendar.getTime();
      
      OrderQuery orderQuery = new OrderQuery();
      orderQuery.setPassengerId(order.getPassengerId());
      orderQuery.setStartFinishTime(start.getTime());
      orderQuery.setAppKey(appKey);
      orderQuery.setStatusArray("5");
      orderQuery.setEndFinishTime(end.getTime());
      Long count = orderService.countByParam(orderQuery);
      if (null != count) {
        countNum=count;
      }
      
      map.put("countNum", countNum);
    }

    return map;
  }

  @Override
  public Long queryRunOrder(OrderQuery orderQuery) {
    return orderService.queryRunOrder(orderQuery);
  }

  @Override
  public DataGrid<Order> findByParams(OrderQuery orderQuery) {

    DataGrid<Order> dataGrid = new DataGrid<Order>();

    List<Order> list = orderService.findByParams(orderQuery);
    for (Order order : list) {

      if (order.getAreaId() == null 
          && !order.getStatus().equals(5) && !order.getStatus().equals(6)) {

        CarType carType = carTypeService.findByCarTypeId(order.getCarTypeId(), order.getAppkey());
        if (null != carType && carType.getAreaId() != null) {
          order.setAreaId(carType.getAreaId());
        } else {
          if (null != order.getServiceTypeId()) {
            ServiceType serviceType =
                serviceTypeService.findByServiceTypeId(order.getServiceTypeId(), order.getAppkey());
            if (serviceType != null) {
              order.setAreaId(serviceType.getAreaId());
            }
          }
        }
      }
    }
    Long count = orderService.countByParams(orderQuery);

    dataGrid.setRows(list);
    dataGrid.setTotal(count);

    return dataGrid;
  }

  @Override
  public DataGrid<Order> findByParamsInBook(OrderQuery orderQuery) {

    DataGrid<Order> dataGrid = new DataGrid<Order>();

    List<Order> list = orderService.findByParamsInBook(orderQuery);
    
    DecimalFormat df = new DecimalFormat("#.00");
    
    if (list.size()>0) {
 		for (int i = 0; i < list.size(); i++) {
 			Double d= Distance.doubleVal(orderQuery.getDriverLatitude(), 
 					orderQuery.getDriverLongitude(), list.get(i).getStartLat(), list.get(i).getStartLng());
 			if (d >= 1) {
 				list.get(i).setStartPlaceToDriverDistanceStr(df.format(d) + "公里");
			} else {
				list.get(i).setStartPlaceToDriverDistanceStr((long) (d * 1000) + "米");
			}
 			list.get(i).setStartPlaceToDriverDistance(d);
 		}
 	}

//    //通过百度API计算每个订单中起始地到司机经纬度的距离以及公里数和分钟数
   /* for (Order order : list) {
		Double startPlaceLatitude = order.getStartLat();
		Double startPlaceLongitude = order.getStartLng();
		JSONObject jsonResult = getStartPlaceToDriverDistance(orderQuery.getDriverLatitude(),orderQuery.getDriverLongitude()
				,startPlaceLatitude,startPlaceLongitude);
		order.setStartPlaceToDriverDistance(Double.parseDouble(jsonResult.getString("distance")));
		//order.setStartPlaceToDriverMinutes(jsonResult.getString("mintues"));
	}*/
    dataGrid.setRows(list);
    return dataGrid;
  }

  @Override
  public Long countByParamsInBook(OrderQuery orderQuery) {
    return orderService.countByParamsInBook(orderQuery);
  }

  public JSONObject getStartPlaceToDriverDistance(Double driverLatitude, Double driverLongitude, Double startPlaceLatitude, Double startPlaceLongitude){

	  RestTemplate restTemplate = new RestTemplate();

	  Map<String,String> kv = new HashMap<String,String>();
	  StringBuilder sb=new StringBuilder();

	  sb.append("http://api.map.baidu.com/routematrix/v2/driving?output={output}");
	  kv.put("output", "json");

	  kv.put("ak","AuNk3YS21DSmHEEvIFDf9dbD");
  	  sb.append("&ak={ak}");

  	  kv.put("tactics","11");
	  sb.append("&tactics={tactics}");

  	  kv.put("origins",driverLatitude.toString()+","+driverLongitude);
	  sb.append("&origins={origins}");

  	  kv.put("destinations",startPlaceLatitude.toString()+","+startPlaceLongitude);
	  sb.append("&destinations={destinations}");

	  String stringResult = restTemplate.getForObject(sb.toString(), String.class, kv);

	  Map<String, Object> map = new HashMap<>();
	  if (null != stringResult) {
		 JSONObject jsonResult = JSONObject.parseObject(stringResult).getJSONObject("result");
		 String distance = jsonResult.getJSONObject("distance").getString("text");
		 String minutes = jsonResult.getJSONObject("distance").getString("text");
		 map.put("distance",distance);
		 map.put("minutes",minutes);
	  }

	  String jsonString = JSONObject.toJSONString(map);

	  return JSONObject.parseObject(jsonString);

  }

  @Override
  public DataGrid<Order> queryOrders(OrderQuery orderQuery) {

    DataGrid<Order> dataGrid = new DataGrid<Order>();

    List<Order> list = orderService.queryByParams(orderQuery);

    Long count = orderService.countByParams(orderQuery);

    dataGrid.setRows(list);
    dataGrid.setTotal(count);

    return dataGrid;
  }

    @Override
  public Long orderCountByEmployId(OrderQuery orderQuery){
      return orderService.countByParams(orderQuery);
  }

  @Override
  public DataGrid<Order> exportOrders(OrderQuery orderQuery) {
    DataGrid<Order> dataGrid = new DataGrid<Order>();

    List<Order> list = orderService.exportOrders(orderQuery);

    Long count = orderService.countByParams(orderQuery);

    dataGrid.setRows(list);
    dataGrid.setTotal(count);
    return dataGrid;
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Order addmore(Long passengerId, String passengerName, String passengerPhone,
      Long companyId, String companyName, Long carTypeId, String channelName, String startAddress,
      Double startLat, Double startLng, Date serverDate, Long employId, String employName,
      String employPhone, Long employCompanyId, String employNo, String employPhoto,
      Double employScore, String memo, String appKey) {
    Order order = new Order();
    order.setPassengerId(passengerId);
    order.setPassengerName(passengerName);
    order.setPassengerPhone(passengerPhone);
    order.setShowPhone(passengerPhone);
    order.setCompanyId(companyId);
    order.setCompanyName(companyName);
    order.setCarTypeId(carTypeId);
    order.setChannelName(channelName);
    order.setStartAddress(startAddress);
    order.setStartLat(startLat);
    order.setStartLng(startLng);
    order.setServerTime(serverDate);
    order.setEmployId(employId);
    order.setEmployName(employName);
    order.setEmployPhone(employPhone);
    order.setEmployCompanyId(employCompanyId);
    order.setEmployNo(employNo);
    order.setEmployPhoto(employPhoto);
    order.setEmployScore(employScore);
    order.setAppkey(appKey);
    int insert = orderService.addmore(order);
    if (insert != 1) {
      throw new RuntimeException("补单失败!!");
    }
    // 保存下单状态记录
    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOperator(employName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(0);
    status.setMemo("服务人员【" + employName + "】补单");
    int sta = statusService.insert(status);
    if (sta != 1) {
      throw new RuntimeException("补单失败!!");
    }
    // 保存派单状态记录
    status.setOrderId(order.getId());
    status.setOperator(employName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(1);
    status.setMemo("【" + employName + "】派单成功");
    sta = statusService.insert(status);
    if (sta != 1) {
      throw new RuntimeException("补单失败!!");
    }
    // 保存接单状态记录
    status.setOrderId(order.getId());
    status.setOperator(employName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(2);
    status.setMemo("【" + employName + "】接单成功");
    sta = statusService.insert(status);
    if (sta != 1) {
      throw new RuntimeException("补单失败!!");
    }
    if (StringUtils.isNotBlank(memo)) {
      OrderMemo orderMemo = new OrderMemo();
      orderMemo.setMemo(memo);
      orderMemo.setOperator(employName);
      orderMemo.setOrderId(order.getId());
      orderMemo.setOrderNo(order.getOrderNo());
      orderMemoService.insert(orderMemo);
    }
    try {
      Car car = carService.findByEmployId(employId, appKey);
      car.setStatus(1);// 补单后把车辆设置为忙碌状态
      carService.update(car);
      order.setCarId(car.getId());
      order.setCarNumber(car.getCarNumber());
      order.setCarName(car.getCarName());
      order.setIsClosed(Boolean.TRUE); // 补单默认不催单
      orderService.update(order);
    } catch (Exception ex) {
      ex.printStackTrace();
    }

    return order;
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Order insert(Long companyId, String companyName, Long passengerId, String passengerName,
      String passengerPhone, String showPhone, Long carTypeId, String channelName,
      String startAddress, String startAddressDetail, Double startLat, Double startLng,
      String endAddress, String endAddressDetail, Double endLat, Double endLng, Date serverDate,
      Double prestartPrice, Double premileagePrice, Double prerunTimePrice, Double budgetPay,
      Long couponId, Integer pretravelTime, Double premileage, String operator,
      String createOrderName, String appKey) {

    Order order = new Order();
    order.setCompanyId(companyId);
    order.setCompanyName(companyName);
    order.setPassengerId(passengerId);
    order.setPassengerName(passengerName);
    order.setPassengerPhone(passengerPhone);
    order.setShowPhone(showPhone);
    order.setCarTypeId(carTypeId);
    order.setChannelName(channelName);
    order.setStartAddress(startAddress);
    order.setStartAddressDetail(startAddressDetail);
    order.setStartLat(startLat);
    order.setStartLng(startLng);
    order.setEndAddress(endAddress);
    order.setEndAddressDetail(endAddressDetail);
    order.setEndLat(endLat);
    order.setEndLng(endLng);
    order.setServerTime(serverDate);
    order.setPreStartPrice(prestartPrice);
    order.setPremileagePrice(premileagePrice);
    order.setPrerunTimePrice(prerunTimePrice);
    order.setBudgetPay(budgetPay);
    order.setPretravelTime(pretravelTime);
    order.setPremileage(premileage);
    order.setAppkey(appKey);
    order.setCouponId(couponId);
    order.setCreateOrderName(createOrderName);
    int insert = orderService.insert(order);
    if (insert != 1) {
      throw new RuntimeException("下单失败!!");
    }
    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOperator(passengerName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(0);
    if ("电话预约".equals(channelName) && StringUtils.isNotBlank(operator)) {
      status.setMemo("管理员【" + operator + "】下单");
    } else {
      status.setMemo("客户【" + order.getPassengerName() + "】下单");
    }

    int sta = statusService.insert(status);
    if (sta != 1) {
      throw new RuntimeException("下单失败!!");
    }
    return order;

  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Order tempToForever(String prePayTypeDetail, Long companyId, String companyName,
      Long passengerId, String passengerName, String passengerPhone, String showPhone,
      Long carTypeId, String channelName, String startAddress, String startAddressDetail,
      Double startLat, Double startLng, String endAddress, String endAddressDetail, Double endLat,
      Double endLng, Date serverDate, Double prestartPrice, Double premileagePrice,
      Double prerunTimePrice, Double budgetPay, Long couponId, Double shouldPay,
      Integer pretravelTime, Double premileage, String appKey) {

    Order order = new Order();
    order.setCompanyId(companyId);
    order.setCompanyName(companyName);
    order.setPassengerId(passengerId);
    order.setPassengerName(passengerName);
    order.setPassengerPhone(passengerPhone);
    order.setShowPhone(showPhone);
    order.setCarTypeId(carTypeId);
    order.setChannelName(channelName);
    order.setStartAddress(startAddress);
    order.setStartAddressDetail(startAddressDetail);
    order.setStartLat(startLat);
    order.setStartLng(startLng);
    order.setEndAddress(endAddress);
    order.setEndAddressDetail(endAddressDetail);
    order.setEndLat(endLat);
    order.setEndLng(endLng);
    order.setServerTime(serverDate);
    order.setPreStartPrice(prestartPrice);
    order.setPremileagePrice(premileagePrice);
    order.setPrerunTimePrice(prerunTimePrice);
    order.setCouponId(couponId);
    order.setPrePayTypeDetail(prePayTypeDetail);
    order.setBudgetPay(budgetPay);

    if ("sign".equals(prePayTypeDetail)) {
      order.setSignMoney(shouldPay);
    } else if ("balance".equals(prePayTypeDetail)) {
      order.setBalanceMoney(shouldPay);
    } else if ("alipay".equals(prePayTypeDetail)) {
      order.setAlipayMoney(shouldPay);
    } else if ("weixin".equals(prePayTypeDetail)) {
      order.setWeixinMoney(shouldPay);
    } else if ("coupon_sign".equals(prePayTypeDetail)) {
      order.setSignMoney(shouldPay);
    } else if ("coupon_balance".equals(prePayTypeDetail)) {
      order.setBalanceMoney(shouldPay);
    } else if ("coupon_alipay".equals(prePayTypeDetail)) {
      order.setAlipayMoney(shouldPay);
    } else if ("coupon_weixin".equals(prePayTypeDetail)) {
      order.setWeixinMoney(shouldPay);
    }

    order.setPretravelTime(pretravelTime);
    order.setPremileage(premileage);
    order.setAppkey(appKey);
    int insert = orderService.insert(order);
    if (insert != 1) {
      throw new RuntimeException("下单失败!!");
    }
    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOperator(passengerName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(0);

    status.setMemo("客户【" + order.getPassengerName() + "】下单");
    int sta = statusService.insert(status);
    if (sta != 1) {
      throw new RuntimeException("下单失败!!");
    }
    return order;

  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Order tempToForeverV4up(String prePayTypeDetail, Long companyId, String companyName,
      Long passengerId, String passengerName, String passengerPhone, String showPhone,
      Long carTypeId, String channelName, String startAddress, String startAddressDetail,
      Double startLat, Double startLng, String endAddress, String endAddressDetail, Double endLat,
      Double endLng, Date serverDate, Double prestartPrice, Double premileagePrice,
      Double prerunTimePrice, Double budgetPay, Long couponId, Long employId, Double shouldPay,
      Integer pretravelTime, Double premileage, String memo, String flightNo, String trainNo,
      Long serviceTypeId, Long areaId, String serverUrl, String appKey) {

    Order order = new Order();
    order.setCompanyId(companyId);
    order.setCompanyName(companyName);
    order.setPassengerId(passengerId);
    order.setPassengerName(passengerName);
    order.setPassengerPhone(passengerPhone);
    order.setShowPhone(showPhone);
    order.setCarTypeId(carTypeId);
    order.setChannelName(channelName);
    order.setStartAddress(startAddress);
    order.setStartAddressDetail(startAddressDetail);
    order.setStartLat(startLat);
    order.setStartLng(startLng);
    order.setEndAddress(endAddress);
    order.setEndAddressDetail(endAddressDetail);
    order.setEndLat(endLat);
    order.setEndLng(endLng);
    order.setServerTime(serverDate);
    order.setPreStartPrice(prestartPrice);
    order.setPremileagePrice(premileagePrice);
    order.setPrerunTimePrice(prerunTimePrice);
    order.setCouponId(couponId);
    order.setPrePayTypeDetail(prePayTypeDetail);
    order.setBudgetPay(budgetPay);

    if ("sign".equals(prePayTypeDetail)) {
      order.setSignMoney(shouldPay);
    } else if ("balance".equals(prePayTypeDetail)) {
      order.setBalanceMoney(shouldPay);
    } else if ("alipay".equals(prePayTypeDetail)) {
      order.setAlipayMoney(shouldPay);
    } else if ("weixin".equals(prePayTypeDetail)) {
      order.setWeixinMoney(shouldPay);
    } else if ("coupon_sign".equals(prePayTypeDetail)) {
      order.setSignMoney(shouldPay);
    } else if ("coupon_balance".equals(prePayTypeDetail)) {
      order.setBalanceMoney(shouldPay);
    } else if ("coupon_alipay".equals(prePayTypeDetail)) {
      order.setAlipayMoney(shouldPay);
    } else if ("coupon_weixin".equals(prePayTypeDetail)) {
      order.setWeixinMoney(shouldPay);
    } else if ("unionpay".equals(prePayTypeDetail)) {
      order.setUnionpayMoney(shouldPay);
    } else if ("coupon_unionpay".equals(prePayTypeDetail)) {
      order.setUnionpayMoney(shouldPay);
    }

    order.setPretravelTime(pretravelTime);
    order.setPremileage(premileage);

    ServiceType type = serviceTypeService.findByServiceTypeId(serviceTypeId, appKey);
    order.setCarTypeId(carTypeId);
    order.setServiceTypeId(type.getId());
    order.setAreaId(areaId);
    com.ybkj.o2o.zhuanche.entity.Order.ServiceType type2 =
        Enum.valueOf(com.ybkj.o2o.zhuanche.entity.Order.ServiceType.class, type.getName());
    order.setServiceType(type2);
    if (StringUtils.isNotBlank(memo)) {
      order.setMemo(memo);
    }
    if (StringUtils.isNotBlank(flightNo)) {
      order.setFlightNo(flightNo);
    }
    if (StringUtils.isNotBlank(trainNo)) {
      order.setTrainNo(trainNo);
    }

    order.setAppkey(appKey);
    orderService.insert(order);
    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOperator(passengerName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(0);

    status.setMemo("客户【" + order.getPassengerName() + "】下单");
    statusService.insert(status);

    if (null != order.getCouponId() && order.getCouponId() != 0) {
      salesApi.updateV4(order.getCouponId(), 2, appKey);
    }
    try {
      PushMessage pushMessage = new PushMessage();
      pushMessage.setAppKey(appKey);
      pushMessage.setTargetId(order.getId());
      pushMessage.setOrderType("zhuanche");
      if (null != employId) {
        boolean bool = daijiaApi.findEmployStatus(serverUrl, employId);// 查询代驾项目司机状态
        if (bool) {
          pushMessage.setMessage("新单派单消息");
          pushMessage.setEmployId(employId);
          pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER_PAIDAN);
        } else {
          pushMessage.setMessage("新单推送消息");
          pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER);
        }
      } else {
        pushMessage.setMessage("新单推送消息");
        pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER);
      }
      rabbitTemplate.convertAndSend(pushMessage);
    } catch (Exception ex) {
      System.err.println("查询代驾项目司机状态或推送错误");
    }

    return order;

  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public int updateStatus(Long orderId, Long employId, String employName, String employPhone,
      Long employCompanyId, String employNo, String employPhoto, Double employScore,
      Long rentalCompanyId, String rentalCompanyName, String action, String operator, String cause,
      String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    if (order != null) {
      order.setUpdated(new Date());
      OrderStatus orderStatus = new OrderStatus();
      orderStatus.setOrderId(order.getId());
      orderStatus.setOrderNo(order.getOrderNo());
      orderStatus.setOperator(operator);
      String message = "";
      if ("paidan".equals(action)) {
        Car car = carService.findByEmployId(employId, appKey);
        message = "派单失败";
        orderStatus.setStatus(1);
        if (car == null) {
          throw new RuntimeException("派单的司机没有车辆");
        }
        order.setCarId(car.getId());
        order.setCarNumber(car.getCarNumber());
        
        //预约用车派单时车辆状态为空闲
        Integer isBook = order.getBookStatus();
        if (null != isBook && isBook > 0) {
        	car.setStatus(0);
            carService.update(car);
		}else {
			car.setStatus(1);
			carService.update(car);
		}
        
        order.setEmployId(employId);
        order.setEmployName(employName);
        order.setEmployPhone(employPhone);
        order.setEmployCompanyId(employCompanyId);
        order.setEmployNo(employNo);
        if (StringUtils.isNotBlank(employPhoto)) {
          try {
            employPhoto = URLDecoder.decode(employPhoto, "UTF-8");
          } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
          }
        }
        order.setEmployPhoto(employPhoto);
        order.setEmployScore(employScore);
        orderStatus.setMemo("【" + operator + "】" + "将订单指派给" + employName);
        order.setStatus(1);
        order.setRentalCompanyId(rentalCompanyId);
        order.setRentalCompanyName(rentalCompanyName);
      } else if ("jiedan".equals(action)) {
        message = "接单失败";
        if (order.getStatus() == 2) {
          throw new RuntimeException(message);
        } else if (order.getStatus() == 0 || order.getStatus() == 1) {
          if (order.getStatus() == 0) { // 直接接单添加一条记录
            OrderStatus status = new OrderStatus();
            status.setOrderId(order.getId());
            status.setOrderNo(order.getOrderNo());
            status.setStatus(1);
            status.setOperator(operator);
            status.setMemo("【" + operator + "】" + "抢单成功");
            statusService.insert(status);
            order.setCompanyId(employCompanyId);
            Car car = carService.findByEmployId(employId, appKey);
            if (car == null) {
              throw new RuntimeException("派单的司机没有车辆");
            }
            //预约用车接单时车辆状态为空闲
            Integer isBook = order.getBookStatus();
            if (null != isBook && isBook > 0) {
            	car.setStatus(0);
                carService.update(car);
    		}else {
    			car.setStatus(1);
    			carService.update(car);
    		}
            order.setCarId(car.getId());
            order.setCarNumber(car.getCarNumber());
          }
          orderStatus.setStatus(2);
          orderStatus.setOperator(operator);
          orderStatus.setMemo("【" + employName + "】" + "接单成功");
          order.setStatus(2);
          order.setEmployId(employId);
          order.setEmployName(employName);
          order.setEmployPhone(employPhone);
          order.setEmployNo(employNo);
          order.setEmployPhoto(employPhoto);
          order.setEmployScore(employScore);
          order.setEmployCompanyId(employCompanyId);
          order.setRentalCompanyId(rentalCompanyId);
          order.setRentalCompanyName(rentalCompanyName);
        }
        order.setIsClosed(Boolean.TRUE);
      } else if ("refuse".equals(action)) {
        message = "拒单失败";
        if (order.getEmployId().equals(employId)) {
          OrderRefuse orderRefuse = new OrderRefuse();
          orderRefuse.setEmployId(order.getEmployId());
          orderRefuse.setEmployName(order.getEmployName());
          orderRefuse.setEmployPhone(order.getEmployPhone());
          orderRefuse.setOrderId(order.getId());
          orderRefuse.setOrderNo(order.getOrderNo());
          orderRefuse.setPassengerId(order.getPassengerId());
          orderRefuse.setPassengerName(order.getPassengerName());
          orderRefuse.setPassengerPhone(order.getPassengerPhone());
          orderRefuse.setMemo(cause);
          orderRefuse.setAppKey(order.getAppkey());
          orderRefuse.setCompanyId(order.getCompanyId());
          orderRefuse.setCompanyName(order.getCompanyName());

          if (refuseService.insert(orderRefuse) != 1) {
            throw new RuntimeException(message);
          }
          orderStatus.setStatus(0);
          orderStatus.setMemo("【" + order.getEmployName() + "】" + "拒绝执行订单");
          order.setStatus(0);
          Car car = carService.findByEmployId(order.getEmployId(), appKey);
          if (null != car) {
            car.setStatus(0);
            carService.update(car);
          }
          order.setEmployId(null);
          order.setEmployName(null);
          order.setEmployPhone(null);
          order.setEmployNo(null);
          order.setEmployPhoto(null);
          order.setEmployScore(null);
          order.setEmployCompanyId(null);
          order.setRentalCompanyId(null);
          order.setRentalCompanyName(null);
        } else {
          throw new RuntimeException(message);
        }
      } else if ("wait".equals(action)) {
        message = "到达预约地开始等待操作失败";
        if (order.getStatus() == 2) {
          order.setStatus(3);
          orderStatus.setOperator(operator);
          orderStatus.setStatus(3);
          orderStatus.setMemo("【" + order.getEmployName() + "】" + "到达预约地");
        } else {
          throw new RuntimeException(message);
        }
      } else if ("run".equals(action)) {
        message = "出发操作失败";
        if (order.getStatus() == 3) {
          order.setStatus(4);
          orderStatus.setOperator(operator);
          orderStatus.setStatus(4);
          orderStatus.setMemo("【" + order.getEmployName() + "】" + "出发");
        } else {
          throw new RuntimeException(message);
        }
      } else if ("callback".equals(action)) {
        message = "收回订单失败";
        order.setStatus(0);
        Car car = carService.findByEmployId(order.getEmployId(), appKey);
        if (car == null) {
          throw new RuntimeException("派单的司机没有车辆");
        }
        car.setStatus(0);
        carService.update(car);
        order.setEmployId(null);
        order.setEmployName(null);
        order.setEmployPhone(null);
        order.setEmployNo(null);
        order.setEmployPhoto(null);
        order.setEmployScore(null);
        order.setEmployCompanyId(null);
        order.setRentalCompanyId(null);
        order.setRentalCompanyName(null);
        orderStatus.setOperator(operator);
        orderStatus.setStatus(0);
        orderStatus.setMemo("【" + operator + "】" + "强行收回订单");
      } else if ("cancel".equals(action)) {
        message = "销单失败";
        if (order.getStatus() < 4) {
          if (null != order.getEmployId()) {
            Car car = carService.findByEmployId(order.getEmployId(), appKey);
            if (car != null) {
              car.setStatus(0);
              carService.update(car);
            }
          }
          orderStatus.setStatus(6);
          orderStatus.setOperator(operator);
          try {
            if(order.getStatus().intValue()>=2){
              orderStatus.setMemo("客户【" + operator + "】" + "违约取消订单");
              dockingSuperviseApi.pushDdwyMessage(order,DdwyMessage.PASSENGERBREAKER,cause);
            }else{
              orderStatus.setMemo("【" + operator + "】" + "取消订单");
              dockingSuperviseApi.pushDdcxMessage(order,DdcxMessage.DDCX_PASSENGER,cause);
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
          order.setStatus(6);
          order.setIsClosed(Boolean.TRUE);
          order.setCancelCause(cause);

          chartService.addDayRecord(order);
        } else {
          message = "订单已销单或已出发,不能销单";
          throw new RuntimeException(message);
        }
      }


      int insert = statusService.insert(orderStatus);

      if (insert != 1) {
        throw new RuntimeException(message);
      }

    }

    if (null != order && StringUtils.isNotBlank(appKey)) {
      order.setAppkey(appKey);
    }
    return orderService.update(order);
  }

  /**
   * 后台直接销单.
   */
  @Override
  public void cancelOrder(Long orderId, String operator, Integer breaker, String cause, String appKey) {
    try {
      Order order = orderService.findByIdAndAppKey(orderId, appKey);
      int oldStatus = order.getStatus();
      if (order.getStatus() != 5 || order.getStatus() != 6) {
        if (null != order.getEmployId()) {
          Car car = carService.findByEmployId(order.getEmployId(), appKey);
          if (car != null) {
            car.setStatus(0);
            carService.update(car);
          }
        }
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setOrderNo(order.getOrderNo());
        orderStatus.setStatus(6);
        orderStatus.setOperator(operator);
        orderStatus.setMemo("【" + operator + "】" + "后台取消订单");
        order.setStatus(6);
        order.setIsClosed(Boolean.TRUE);
        order.setCancelCause(cause);
        statusService.insert(orderStatus);
        chartService.addDayRecord(order);
        orderService.updateIngoreNull(order);
        /*if(oldStatus>=2){
          dockingSuperviseApi.pushDdwyMessage(order,breaker,cause);
        }else{*/
          dockingSuperviseApi.pushDdcxMessage(order, DdcxMessage.DDCX_PLATFORM,cause);
        //}
        //消息推送至队列

      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }

  }

  @Override
  public int update(Order order) {
    int insert = orderService.updateIngoreNull(order);
    return insert;
  }

  @Override
  public List<Order> findByEmployId(OrderQuery orderQuery) {
    return orderService.findByEmployId(orderQuery);
  }

  @Override
  public ChartYear dataForYear(Integer year, Long companyId, String appKey) {
    ChartYear chartYear = chartService.dataForYear(year, companyId, appKey);
    return chartYear;
  }

  @Override
  public ChartMonth dataForMonth(Integer year, Long companyId, Integer month, String appKey) {
    ChartMonth chartMonth = chartService.dataForMonth(year, month, companyId, appKey);
    return chartMonth;
  }

  @Override
  public ChartDay dataForDay(
      Integer year, Integer month, Integer day, Long companyId, String appKey) {
    ChartDay chartDay = chartService.dataForChartDay(year, month, day, companyId, appKey);
    return chartDay;
  }

  @Override
  public PageVo<OrderFromSourceVo> orderFromSource(Date date1, Date date2, Long companyId,
      String appKey) {
    PageVo<OrderFromSourceVo> source =
        orderService.orderFromSource(date1, date2, companyId, appKey);
    return source;
  }

  /**
   * 查询后十个催单的订单.
   */

  public List<Order> findHastenOrderAppKey(String appKey) {

    List<Order> list = orderService.findHastenOrder(appKey);
    return list;
  }

  @Override
  public Order findFinishedByDriverWithDate(Long employId, Date start, Date end, String appKey) {

    return orderService.findByDriverAndFinishTime(employId, start, end, appKey);

  }

  @Override
  public List<Order> findMonthOrder(Integer year, Integer month, String appKey) {
    return orderService.findMonthOrder(year, month, appKey);
  }

  @Override
  public PageVo<MemberOrderVo> findMemberOrder(Date startTime, Date endTime, Long companyId,
      String appKey) {
    return orderService.findMemberOrder(startTime, endTime, companyId, appKey);
  }

  /**
   * 统计数据.
   */

  public PageVo<DriverOrderVo> driverAchievement(Date date1, Date date2, Long empCompanyId,
      String appKey) {
    PageVo<DriverOrderVo> source =
        orderService.driverAchievement(date1, date2, empCompanyId, appKey);
    return source;
  }

  @Override
  public PageVo<CompanyOrderVo> companyOrder(Date date1, Date date2, String appKey) {
    PageVo<CompanyOrderVo> source = orderService.companyOrder(date1, date2, appKey);
    return source;
  }

  @Override
  public Order finishTask(Long orderId, String afterPayTypeDetail, Double companyProfit,
      Double employProfit, Double signMoney, Double balanceMoney, Double alipayMoney,
      Double weixinMoney, Double unionpayMoney,
      Double cashMoney, String appKey, String operating, String endAddress,
      Double endLat, Double endLng, Integer runTime, Double mileage, Integer midwayWait,
      Double realPay, Double guoluMoney, Double baoxiaoMoney, String baoxiaoMemo, Long finishTime) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    if (StringUtils.isNotBlank(afterPayTypeDetail)) {
      // 后支付类型 cashMoney(代付) sign(签单) balance(余额) alipay(支付宝) weixin(微信)
      order.setAfterPayTypeDetail(afterPayTypeDetail);
    }
    order.setSignMoney(signMoney);
    order.setBalanceMoney(balanceMoney);
    order.setAlipayMoney(alipayMoney);
    order.setWeixinMoney(weixinMoney);
    order.setUnionpayMoney(unionpayMoney);
    order.setCashMoney(cashMoney);
    order.setCompanyProfit(companyProfit);
    order.setEmployProfit(employProfit);
    order.setStatus(5);
    order.setFinishTime(new Date());
    String finialStr = "【" + order.getEmployName() + "】" + "到达目的地，并且结算完成";
    if (StringUtils.isNotBlank(operating)) { // 后台完工
      finialStr = "管理员【" + operating + "】手动完工";
      order.setOperating(operating);

      order.setRunTime(runTime);
      order.setMileage(mileage);
      order.setMidwayWait(midwayWait);
      order.setRealPay(realPay);
      order.setGuoluMoney(guoluMoney);
      if (StringUtils.isNotBlank(endAddress) && endLat != null && endLng != null) {
        order.setEndAddress(endAddress);
        order.setEndLat(endLat);
        order.setEndLng(endLng);
      }
      if (baoxiaoMoney != null && baoxiaoMoney > 0) {
        order.setBaoxiao(Boolean.TRUE);
        order.setBaoxiaoMoney(baoxiaoMoney);
        order.setBaoxiaoMemo(baoxiaoMemo);
      }
      order.setFinishTime(new Date(finishTime));
      order.setTreatment(Boolean.TRUE);
      order.setTreatmentDate(new Date());
    }

    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOrderNo(order.getOrderNo());
    status.setStatus(5);
    status.setOperator(order.getPassengerName());

    status.setMemo(finialStr + ",行程时间为：" + order.getRunTime() + "分钟，总等待时间为："
        + order.getMidwayWait() + "分钟,行驶里程为：" + order.getMileage() + "公里");
    statusService.insert(status);
    orderService.updateIngoreNull(order);
    new Thread(() -> {
      chartService.addDayRecord(order);
    }).start();

    return order;
  }

  @Override
  public Order complete(Long orderId, Double realPay, Double guoluMoney, Double yuanchengMoney,
      Double otherMoney, Double startPrice, Double mileagePrice, Double runTimePrice,
      Double waitPrice, String endAddress, Double endLat, Double endLng, Double mileage,
      Integer midwayWait, Integer runTime, Double couponMoney, String appKey,
      String prePayTypeDetail, String memo,Double justKilometres,BigDecimal justMoney,
      Double ksMileage, Double ddMileage) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    order.setTreatment(Boolean.TRUE);
    order.setTreatmentDate(new Date());
    if (guoluMoney != null && guoluMoney != 0) {
      order.setGuoluMoney(guoluMoney);
    }
    if (yuanchengMoney != null && yuanchengMoney != 0) {
      order.setYuanchengMoney(yuanchengMoney);
    }
    if (otherMoney != null && otherMoney != 0) {
      order.setOtherMoney(otherMoney);
    }
    if (realPay != null) {
      order.setRealPay(realPay);
    }
    if (startPrice != null) {
      order.setStartPrice(startPrice);
    }
    if (mileagePrice != null) {
      order.setMileagePrice(mileagePrice);
    }
    if (runTimePrice != null) {
      order.setRunTimePrice(runTimePrice);
    }
    if (waitPrice != null) {
      order.setWaitPrice(waitPrice);
    }
    if (mileage != null) {
      order.setMileage(mileage);
    }
    if (midwayWait != null) {
      order.setMidwayWait(midwayWait);
    }
    if (runTime != null) {
      order.setRunTime(runTime);
    }
    if (couponMoney != null) {
      order.setCouponMoney(couponMoney);
    }
    if (StringUtils.isNotBlank(endAddress)) {
      order.setEndAddress(endAddress);
      order.setEndLat(endLat);
      order.setEndLng(endLng);
    }
    if (StringUtils.isNotBlank(prePayTypeDetail)) {
      order.setPrePayTypeDetail(prePayTypeDetail);
    }
    if (StringUtils.isNotBlank(memo)) {
      order.setEmployMemo(memo);
    }
    if (justKilometres != null) {
      order.setJustKilometres(justKilometres);
    }
    if (justMoney != null) {
      order.setJustMoney(justMoney);
    }
    if (ksMileage != null) {
      order.setKsMileage(ksMileage);
    }
    if (ddMileage != null) {
      order.setDdMileage(ddMileage);
    }
    orderService.updateIngoreNull(order);
    if (order.getCarId() != null) {
      Car car = carService.findByCarId(order.getCarId(), appKey);
      if (null != car) {
        car.setStatus(0);
        carService.update(car);
      }
    }
    return order;
  }

  @Override
  public PageVo<DriverOrderDetailVo> driverOrderDetailVo(Long driverId, Date start, Date end,
      Integer page, Integer rows, String appKey) {
    PageVo<DriverOrderDetailVo> pageVo =
        orderService.driverOrderDetailVo(driverId, start, end, page, rows, appKey);
    return pageVo;
  }

  /**
   * 统计接口.
   */
  public Map<String, Object> chart(Long companyId, Long start, Long end, Boolean maincompany,
      String appKey) {
    Date startTime = new Date(start);
    Date endTime = new Date(end);
    long orderNumber = 0;// 自己公司司机完成的订单数量
    long runOrderNumber = 0;// 自己公司司机执行中的订单数量

    long otherOrderNumber = 0;// 其他公司司机完成的订单数量
    long runOtherOrderNumber = 0;// 其他公司司机执行中的订单数量

    long cancelOrderNumber = 0;// 自己公司销单的订单数量

    long inOrderNumber = 0;// 其他公司创建的订单本公司司机完成的订单数量
    

    double orderRealCash = 0.0;// 本公司创建由本公司司机完成的订单金额
    double otherOrderRealCash = 0.0;// 本公司创建由其他公司司机完成的订单金额
    double inOrderRealCash = 0.0;// 其他公司创建由本公司司机完成的订单金额

    double companyProfit = 0.0;// 公司收入
    double otherCompanyProfit = 0.0;// 本公司创建由其他公司司机完成的收入
    double inCompanyProfit = 0.0;// 其他公司创建由本公司司机完成的收入

    double driverProfit = 0.0;// 司机收入
    double otherDriverProfit = 0.0;// 其他公司的司机完成的收入
    double inDriverProfit = 0.0;// 其他公司创建订单由本公司的司机完成的收入

    double orderFinishedCouponMoneyThis = 0.0;// 由本公司司机完成订单优惠券金额;
    double orderFinishedCouponMoneyGetout = 0.0;// 由平台其它公司司机完成订单优惠券金额;
    double orderFinishedCouponMoneyComein = 0.0;// 平台其它公司创建、由本公司司机完成的订单优惠券金额;

    double orderFinishedPayMoneyThis = 0.0;
    double orderFinishedPayMoneyGetout = 0.0;
    double orderFinishedPayMoneyComein = 0.0;
    double totalGuoluMoney = 0.0;// 所有过路费
    long totalAmount = 0;// 所有公司单量
    long totalCancelAmount = 0;// 所有公司销单量
    double totalRealCash = 0.0;// 所有公司订单金额
    double totalPayMoney = 0.0; // 所有支付金额
    double totalCompanyProfit = 0.0; // 所有公司收入
    double totalDriverProfit = 0.0; // 所有司机收入
    
    final Map<String, Object> finishMap =
        orderService.countFinishByCompay(companyId, startTime, endTime, appKey); // 本公司创建本公司服务人员完成订单

    final Long runTotalCompany = orderService.countRunByCompany(
        companyId, startTime, endTime, appKey); // 本公司创建本公司服务人员执行中订单
    
    runOrderNumber = runTotalCompany;
    
    // 本公司创建由其他公司服务人员完成订单
    final Map<String, Object> finishMapNotEmp =
        orderService.countFinishByNotCompay(companyId, startTime, endTime, appKey);

    // 本公司创建由其他公司服务人员执行订单
    Long runTotalNotEmp = orderService.countRunByNotCompany(companyId, startTime, endTime, appKey); 
    
    runOtherOrderNumber = runTotalNotEmp;
    
    // 自己公司销单的订单数量
    Long cancel = orderService.countCancelByCompany(companyId, startTime, endTime, appKey);
    cancelOrderNumber = cancel;
    // 平台其它公司创建、由本公司服务人员完成的订单
    final Map<String, Object> finishMapNotCompany =
        orderService.countFinishByNotCompanyAndDriver(companyId, startTime, endTime, appKey); 
    // 平台其它公司创建、由本公司服务人员执行的订单
    Long runNotCompany =
        orderService.countRunByNotCompanyNotDriver(companyId, startTime, endTime, appKey);
    long inRunOrderNumber = 0;// 其他公司创建的订单本公司司机正在执行的订单数量
    inRunOrderNumber = runNotCompany;
    if (finishMap != null) {
      orderNumber = (long) finishMap.getOrDefault("total", 0L);
      orderRealCash = (double) finishMap.getOrDefault("total_pay", 0.0);
      orderFinishedCouponMoneyThis = (double) finishMap.getOrDefault("total_coupon", 0.0);
      orderFinishedPayMoneyThis = orderRealCash - orderFinishedCouponMoneyThis;
      companyProfit = (double) finishMap.getOrDefault("total_company_profit", 0.0);
      driverProfit = (double) finishMap.getOrDefault("total_employ_profit", 0.0);
    }

    if (finishMapNotEmp != null) {
      otherOrderNumber = (long) finishMapNotEmp.getOrDefault("total", 0L);
      otherOrderRealCash = (double) finishMapNotEmp.getOrDefault("total_pay", 0.0);
      orderFinishedCouponMoneyGetout = (double) finishMapNotEmp.getOrDefault("total_coupon", 0.0);
      orderFinishedPayMoneyGetout = otherOrderRealCash - orderFinishedCouponMoneyGetout;
      otherCompanyProfit = (double) finishMapNotEmp.getOrDefault("total_company_profit", 0.0);
      otherDriverProfit = (double) finishMapNotEmp.getOrDefault("total_employ_profit", 0.0);
    }

    if (finishMapNotCompany != null) {
      inOrderNumber = (long) finishMapNotCompany.getOrDefault("total", 0L);
      inOrderRealCash = (double) finishMapNotCompany.getOrDefault("total_pay", 0.0);
      orderFinishedCouponMoneyComein =
          (double) finishMapNotCompany.getOrDefault("total_coupon", 0.0);
      orderFinishedPayMoneyComein = inOrderRealCash - orderFinishedCouponMoneyComein;
      inCompanyProfit = (double) finishMapNotCompany.getOrDefault("total_company_profit", 0.0);
      inDriverProfit = (double) finishMapNotCompany.getOrDefault("total_employ_profit", 0.0);
    }


    if (maincompany) {

      Map<String, Object> mainMap = orderService.countMain(startTime, endTime, appKey);
      if (mainMap != null) {
        totalAmount = orderService.countByAppKey(startTime, endTime, appKey);
        totalRealCash = (double) mainMap.getOrDefault("real_pay", 0.0);
        totalCompanyProfit = (double) mainMap.getOrDefault("company_profit", 0.0);
        totalDriverProfit = (double) mainMap.getOrDefault("emp_profit", 0.0);
        totalPayMoney = (double) mainMap.getOrDefault("zhifu_pay", 0.0);
        totalGuoluMoney = (double) mainMap.getOrDefault("guolu_money", 0.0);
      }

      totalCancelAmount = orderService.countCancelAll(startTime, endTime, appKey);
    }

    Map<String, Object> map = new HashMap<String, Object>();

    map.put("totalGuoluMoney", totalGuoluMoney);
    map.put("totalAmount", totalAmount);
    map.put("totalCancelAmount", totalCancelAmount);
    map.put("totalRealCash", totalRealCash);
    map.put("totalPayMoney", totalPayMoney);
    map.put("totalCompanyProfit", totalCompanyProfit);
    map.put("totalDriverProfit", totalDriverProfit);
    map.put("orderNumber", orderNumber);
    map.put("runOrderNumber", runOrderNumber);
    map.put("otherOrderNumber", otherOrderNumber);
    map.put("runOtherOrderNumber", runOtherOrderNumber);
    map.put("cancelOrderNumber", cancelOrderNumber);
    map.put("inOrderNumber", inOrderNumber);
    map.put("inRunOrderNumber", inRunOrderNumber);
    long sumOrderNumber = 0;// 合计订单数量
    sumOrderNumber =
        orderNumber + runOrderNumber + otherOrderNumber + runOtherOrderNumber + cancelOrderNumber
            + inOrderNumber + inRunOrderNumber;

    map.put("sumOrderNumber", sumOrderNumber);
    map.put("orderRealCash", orderRealCash);
    map.put("otherOrderRealCash", otherOrderRealCash);
    map.put("inOrderRealCash", inOrderRealCash);
    Double sumOrderRealCash = 0.0;// 合计订单金额
    sumOrderRealCash = orderRealCash + otherOrderRealCash + inOrderRealCash;
    double orderTotalPayMoney = 0.0;

    map.put("sumOrderRealCash", sumOrderRealCash);
    orderTotalPayMoney =
        orderFinishedPayMoneyComein + orderFinishedPayMoneyGetout + orderFinishedPayMoneyThis;
    map.put("orderTotalPayMoney", orderTotalPayMoney);
    map.put("orderFinishedPayMoney_this", orderFinishedPayMoneyThis);
    map.put("orderFinishedPayMoney_getout", orderFinishedPayMoneyGetout);

    map.put("orderFinishedPayMoney_comein", orderFinishedPayMoneyComein);

    map.put("companyProfit", companyProfit);
    map.put("otherCompanyProfit", otherCompanyProfit);
    map.put("inCompanyProfit", inCompanyProfit);
    Double sumCompanyProfit = 0.0;// 合计公司收入
    sumCompanyProfit = companyProfit + otherCompanyProfit + inCompanyProfit;

    map.put("sumCompanyProfit", sumCompanyProfit);

    map.put("driverProfit", driverProfit);
    map.put("otherDriverProfit", otherDriverProfit);
    map.put("inDriverProfit", inDriverProfit);
    Double sumDriverProfit = 0.0;// 合计司机收入
    sumDriverProfit = driverProfit + otherDriverProfit + inDriverProfit;
    map.put("sumDriverProfit", sumDriverProfit);
    Double totalCouponMoney = 0.0; // 合计优惠券金额
    totalCouponMoney =
        orderFinishedCouponMoneyThis + orderFinishedCouponMoneyGetout
            + orderFinishedCouponMoneyComein;
    map.put("totalCouponMoney", totalCouponMoney);
    map.put("orderTotalCouponMoney", totalCouponMoney);
    map.put("orderFinishedCouponMoney_this", orderFinishedCouponMoneyThis);
    map.put("orderFinishedCouponMoney_getout", orderFinishedCouponMoneyGetout);
    map.put("orderFinishedCouponMoney_comein", orderFinishedCouponMoneyComein);
    return map;

  }

  @Override
  public Long countByParam(OrderQuery orderQuery) {
    return orderService.countByParam(orderQuery);
  }

  @Override
  public Order findLastOrder(OrderQuery orderQuery) {

    List<Order> list = orderService.findMyFinishOrder(orderQuery);

    if (CollectionUtils.isEmpty(list)) {
      Long orderId = null;
      Order order = list.get(list.size() - 1);
      orderId = order.getId();
      List<OrderStatus> statusList = statusService.findByOrderId(orderId);
      if (statusList != null && statusList.size() != 0) {
        OrderStatus status = statusList.get(statusList.size() - 1);
        Date finishTime = status.getCreated();
        order.setFinishTime(finishTime);
        return order;
      }
    }
    return null;
  }

  /**
   * 修改订单金额.
   */

  @Override
  public void updateRealMoney(Long orderId, Double couponMoney, Double cashMoney, Double signMoney,
      Double balanceMoney, Double alipayMoney, Double weixinMoney, String operator, String content,
      String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    final Double oldRealPay = order.getRealPay();
    order.setUpdated(new Date());
    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOrderNo(order.getOrderNo());
    status.setStatus(5);
    status.setOperator(operator);
    status.setMemo("【" + operator + "】" + "修改订单金额" + "原金额为" + order.getRealPay() + "元,修改后金额为:"
        + cashMoney + "元,修改原因:" + content);
    statusService.insert(status);
    order.setRealPay(cashMoney);
    order.setCashMoney(cashMoney);
    if (couponMoney != null) {
      order.setCouponMoney(couponMoney);
    }
    if (signMoney != null) {
      order.setSignMoney(signMoney);
    }
    if (balanceMoney != null) {
      order.setBalanceMoney(balanceMoney);
    }
    if (alipayMoney != null) {
      order.setAlipayMoney(alipayMoney);
    }
    if (weixinMoney != null) {
      order.setWeixinMoney(weixinMoney);
    }
    orderService.updateIngoreNull(order);
    chartService.updateRealMoney(order, oldRealPay);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Error jiedan(Long orderId, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    order.setUpdated(new Date());
    OrderStatus orderStatus = new OrderStatus();
    orderStatus.setOrderId(order.getId());
    orderStatus.setOrderNo(order.getOrderNo());
    orderStatus.setOperator(order.getEmployName());

    orderStatus.setStatus(2);
    orderStatus.setOperator(order.getEmployName());
    orderStatus.setMemo("【" + order.getEmployName() + "】" + "接单成功");
    order.setStatus(2);
    order.setIsClosed(Boolean.TRUE); // 接单时去掉催单提示框

    int insert = statusService.insert(orderStatus);

    int update = orderService.updateIngoreNull(order);
    if (insert != 1 || update != 1) {
      throw new RuntimeException("接单失败");
    }
    
    return ErrorConstantV4.SUCCESS;
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Error refuse(Long orderId, Long employId, String cause, String operator, String appKey) {

    Order order = orderService.findByIdAndAppKey(orderId, appKey);

    order.setUpdated(new Date());

    OrderStatus orderStatus = new OrderStatus();
    orderStatus.setOrderId(order.getId());
    orderStatus.setOrderNo(order.getOrderNo());
    orderStatus.setOperator(operator);
    orderStatus.setStatus(0);
    orderStatus.setMemo("【" + order.getEmployName() + "】" + "拒绝执行订单");
    int insert = statusService.insert(orderStatus);
    if (insert != 1) {
      throw new RuntimeException("拒单失败");
    }
    OrderRefuse orderRefuse = new OrderRefuse();
    orderRefuse.setEmployId(order.getEmployId());
    orderRefuse.setEmployName(order.getEmployName());
    orderRefuse.setEmployPhone(order.getEmployPhone());
    orderRefuse.setOrderId(order.getId());
    orderRefuse.setOrderNo(order.getOrderNo());
    orderRefuse.setPassengerId(order.getPassengerId());
    orderRefuse.setPassengerName(order.getPassengerName());
    orderRefuse.setPassengerPhone(order.getPassengerPhone());
    orderRefuse.setMemo(cause);
    orderRefuse.setAppKey(order.getAppkey());
    orderRefuse.setCompanyId(order.getCompanyId());
    orderRefuse.setCompanyName(order.getCompanyName());
    int rinsert = refuseService.insert(orderRefuse);
    if (rinsert != 1) {
      throw new RuntimeException("拒单失败");
    }
    order.setStatus(0);
    Car car = carService.findByEmployId(order.getEmployId(), appKey);
    if (null != car) {
      car.setStatus(0);
      carService.update(car);
    }
    order.setEmployId(null);
    order.setEmployName(null);
    order.setEmployPhone(null);
    order.setEmployNo(null);
    order.setEmployPhoto(null);
    order.setEmployScore(null);
    order.setEmployCompanyId(null);
    order.setRentalCompanyId(null);
    order.setRentalCompanyName(null);

    int update = orderService.update(order);

    if (update != 1) {
      throw new RuntimeException("拒单失败");
    }
    return ErrorConstantV4.SUCCESS;
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Error waitV4(Long orderId, String operator, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);

    if (order.getStatus() == 2) {
      OrderStatus orderStatus = new OrderStatus();
      orderStatus.setOrderId(order.getId());
      orderStatus.setOrderNo(order.getOrderNo());
      orderStatus.setOperator(operator);
      orderStatus.setStatus(3);
      orderStatus.setMemo("【" + order.getEmployName() + "】" + "到达预约地");
      
      //预约订单时在司机到达预约地等待时将车辆设置为忙碌
      Integer isBook = order.getBookStatus();
      if (null != isBook && isBook > 0) {
    	  Car car = carService.findByEmployId(order.getEmployId(), appKey);
    	  if (null != car.getStatus() && car.getStatus() > 0) {
    		  return ErrorConstantV4.YUYUE_CANT_ACCPET;
    	  }
    	  car.setStatus(1);
    	  carService.update(car);
      }

      order.setUpdated(new Date());
      order.setStatus(3);

      int insert = statusService.insert(orderStatus);
      int update = orderService.updateIngoreNull(order);
      if (insert != 1 || update != 1) {
        throw new RuntimeException("等待失败");
      }
      return ErrorConstantV4.SUCCESS;
    } else if (order.getStatus() == 6) {
      return ErrorConstantV4.ORDER_HASBEEN_CANCEL;
    } else {
      return ErrorConstantV4.ORDER_STATUS_ERROR;
    }
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Error runV4(Long orderId, String operator, String appKey,
      String realStartAddress,Double realStartLat,Double realStartLng) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    if (order.getStatus() != 3) {
      return ErrorConstantV4.ORDER_STATUS_ERROR;
    }

    OrderStatus orderStatus = new OrderStatus();
    orderStatus.setOrderId(order.getId());
    orderStatus.setOrderNo(order.getOrderNo());
    orderStatus.setOperator(operator);
    orderStatus.setStatus(4);
    orderStatus.setMemo("【" + order.getEmployName() + "】" + "出发");

    order.setUpdated(new Date());
    order.setStatus(4);

    order.setRealStartAddress(realStartAddress);
    order.setRealStartLat(realStartLat);
    order.setRealStartLng(realStartLng);
    int insert = statusService.insert(orderStatus);
    int update = orderService.updateIngoreNull(order);
    if (insert != 1 || update != 1) {
      throw new RuntimeException("出发失败");
    }
    return ErrorConstantV4.SUCCESS;
  }

  /**
   * V4抢单.
   */

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Error grab(Long orderId, Long employId, String employName, String employPhone,
      Long employCompanyId, String employNo, String employPhoto, Double employScore,
      Long rentalCompanyId, String rentalCompanyName, String operator, String appKey) {

    Order order = orderService.findByIdAndAppKey(orderId, appKey);

    if (order.getStatus() != 0) {
      return ErrorConstantV4.ORDER_HASBEEN_RUSHED;
    }
    Car car = carService.findByEmployId(employId, appKey);
    if (car == null) {
      return ErrorConstantV4.ORDER_HASBEEN_RUSHED;
    }
    order.setCarId(car.getId());
    order.setCarNumber(car.getCarNumber());

    order.setUpdated(new Date());
    order.setStatus(2);
    order.setEmployId(employId);
    order.setEmployName(employName);
    order.setEmployPhone(employPhone);
    order.setEmployNo(employNo);
    order.setEmployPhoto(employPhoto);
    order.setEmployScore(employScore);
    order.setEmployCompanyId(employCompanyId);
    order.setRentalCompanyId(rentalCompanyId);
    order.setRentalCompanyName(rentalCompanyName);

    int update = orderService.updateIngoreNull(order);
    if (update == 1) {
      OrderStatus status = new OrderStatus();
      status.setOrderId(order.getId());
      status.setOrderNo(order.getOrderNo());
      status.setStatus(2);
      status.setOperator(operator);
      status.setMemo("【" + operator + "】" + "抢单成功");

      if (statusService.insert(status) != 1) {
        throw new RuntimeException("抢单失败");
      }
    } else {
      throw new RuntimeException("抢单失败");
    }
    if (null==order.getBookStatus()||order.getBookStatus()!=1) {
    	car.setStatus(1);
        if (carService.update(car) != 1) {
          throw new RuntimeException("抢单失败");
        }
	} 

    return ErrorConstantV4.SUCCESS;
  }

  /**
   * V4销单.
   */
  @Override
  @Transactional(rollbackFor = Exception.class)
  public Error cancelV4(Long orderId, String cause, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    if (order.getStatus() == 6) {
      return ErrorConstantV4.ORDER_HASBEEN_CANCEL;
    }
    if (order.getStatus() != 5) { // 已派单,已接单

      if (null != order.getEmployId()) {
        Car car = carService.findByEmployId(order.getEmployId(), appKey);
        if (car != null) {
          car.setStatus(0);
          carService.update(car);
        }
      }
      OrderStatus orderStatus = new OrderStatus();
      orderStatus.setOrderId(order.getId());
      orderStatus.setOrderNo(order.getOrderNo());
      orderStatus.setStatus(6);
      orderStatus.setOperator(order.getEmployName());
      orderStatus.setMemo("【" + order.getEmployName() + "】" + "取消订单");
      int insert = statusService.insert(orderStatus);
      if (insert != 1) {
        throw new RuntimeException("销单失败");
      }
      order.setStatus(6);
      order.setIsClosed(Boolean.TRUE);
      order.setCancelCause(cause);

      int update = orderService.updateIngoreNull(order);
      chartService.addDayRecord(order);
      if (update != 1) {
        throw new RuntimeException("销单失败");
      }
    } else {
      return ErrorConstantV4.ORDER_STATUS_ERROR;
    }

    return ErrorConstantV4.SUCCESS;
  }

  @Override
  public List<Order> findOrderByEmployId(OrderQuery orderQuery) {
    return orderService.findByParams(orderQuery);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void baoxiao(Long orderId, Double baoxiaoMoney, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    order.setBaoxiao(Boolean.TRUE);
    order.setBaoxiaoMoney(baoxiaoMoney);
    orderService.update(order);
  }

  @Override
  public ResultTransport createV4up(Long passengerId, String passengerName, String passengerPhone,
      String userPhone ,int passengerGender, Long companyId, String companyName, String channelName, Date serverDate,
      String startAddress, String startAddressDetail, Double startLat, Double startLng,
      String endAddress, String endAddressDetail, Double endLat, Double endLng, Boolean prePay,
      Integer travelTime, Double mileage, String memo, String flightNo, String trainNo,
      String operator, Long serviceTypeId, String serviceType, String carTypes, String couponIdStr,
      String serverUrl, Double couponMoney, String createOrderName, String useType, String appKey,
      Integer bookStatus,BigDecimal makePrice ,Integer isMakePrice,Long driverId) {
    List<Order> orderList = new ArrayList<Order>();
    List<ServiceEntity> list = new ArrayList<ServiceEntity>();
    list = JSON.parseArray(carTypes, ServiceEntity.class);
    Integer orderNumber = 0;
    Double orderPayMoney = 0.0;
    for (ServiceEntity serviceEntity : list) { // 遍历车辆类型
      orderNumber += serviceEntity.getNumber(); // 车型用车数量
      orderPayMoney = orderPayMoney + (serviceEntity.getNumber() * serviceEntity.getBudgetPay());
    }

    OrderGroup orderGroup = new OrderGroup();
    if (orderNumber > 1) {
      orderGroup.setPrepay(prePay);
      orderGroup.setPayMoney(orderPayMoney);
      orderGroup.setAppKey(appKey);
      orderGroupService.insert(orderGroup);
    }
    Map<String, Object> typeCoupon = new HashMap<String, Object>();
    if (StringUtils.isNotBlank(couponIdStr)) {
      String[] split = couponIdStr.split(",");
      for (int i = 0; i < split.length; i++) {
        String sp = split[i];
        String[] split2 = sp.split("-");
        for (int j = 0; j < split2.length; j++) {
          if (!"0".equals(split2[1])) {
            typeCoupon.put(split2[0], split2[1]);
          } else {
            typeCoupon.remove(split2[0]);
          }
        }
      }
    }
    String couponIdString = "";
    String orderIds = "";
    ServiceType type = new ServiceType();
    for (ServiceEntity serviceEntity : list) { // 遍历车辆类型
      String couponIds = serviceEntity.getCouponIds();
      List<String> couponIdList = new ArrayList<String>();// 多张优惠券id
      if (StringUtils.isNotBlank(couponIds)) {
        String[] split = couponIds.split(",");
        Collections.addAll(couponIdList, split);
      }
      List<String> employIdList = new ArrayList<String>();// 该车型的收藏司机id
      String employIds = serviceEntity.getEmployIds();
      if (StringUtils.isNotBlank(employIds)) {
        String[] split = employIds.split(",");
        Collections.addAll(employIdList, split);
      }
      Long carTypeId = serviceEntity.getCarTypeId();
      Double budgetPay = serviceEntity.getBudgetPay();
      Double startPrice = serviceEntity.getStartPrice();
      Double mileagePrice = serviceEntity.getMileagePrice();
      Double travelTimePrice = serviceEntity.getTravelTimePrice();
      Long areaId = serviceEntity.getAreaId();
      if (areaId==0){
        List<ServiceType> serverTypeList = serviceTypeService.findByCarTypeIdAndCarTypeCompanyId(carTypeId, companyId, appKey);
        if (!CollectionUtils.isEmpty(serverTypeList)){
          ServiceType serviceTypeNew=serverTypeList.get(0);
          areaId=serviceTypeNew.getAreaId();
        }
      }
      if (serviceTypeId != null) {
        type = serviceTypeService.findByServiceTypeId(serviceTypeId, appKey);
      } else {
        type = serviceTypeService.findByNameAndCarTypeId(carTypeId, companyId, serviceType, appKey);
      }
      Integer number = serviceEntity.getNumber(); // 车型用车数量
      for (int i = 0; i < number; i++) {
        Order order = new Order();
        order.setPassengerId(passengerId);
        order.setPassengerName(passengerName);
        order.setPassengerPhone(passengerPhone);
        order.setShowPhone(userPhone);
        order.setCompanyId(companyId);
        order.setCompanyName(companyName);
        order.setChannelName(channelName);
        order.setServerTime(serverDate);
        order.setStartAddress(startAddress);
        order.setStartAddressDetail(startAddressDetail);
        order.setStartLat(startLat);
        order.setStartLng(startLng);
        order.setEndAddress(endAddress);
        order.setEndAddressDetail(endAddressDetail);
        order.setEndLat(endLat);
        order.setEndLng(endLng);
        if(isMakePrice==null || isMakePrice==0) {
          order.setBudgetPay(budgetPay);
        }else {
          order.setBudgetPay(Double.valueOf(String.valueOf(makePrice)));
        }
        order.setPreStartPrice(startPrice);
        order.setPremileagePrice(mileagePrice);
        order.setPrerunTimePrice(travelTimePrice);
        order.setPretravelTime(travelTime);
        order.setPremileage(mileage);
        order.setCarTypeId(carTypeId);
        
        order.setUseType(useType); //用车类型
        
        order.setAreaId(areaId);
        order.setCreateOrderName(createOrderName);
        order.setAppkey(appKey);
        order.setBookStatus(bookStatus);
        order.setServiceTypeId(type.getId());
        if(isMakePrice==null){
          order.setIsMakePrice(0);
        }else {
          order.setIsMakePrice(isMakePrice);//订单定价
        }
        if(makePrice==null) {
          order.setMakePrice(new BigDecimal(0));
        }else {
          order.setMakePrice(makePrice);//是否订单定价
        }

        com.ybkj.o2o.zhuanche.entity.Order.ServiceType type2 =
            Enum.valueOf(com.ybkj.o2o.zhuanche.entity.Order.ServiceType.class, type.getName());
        order.setServiceType(type2);
        if (StringUtils.isNotBlank(memo)) {
          order.setMemo(memo);
        }
        if (StringUtils.isNotBlank(flightNo)) {
          order.setFlightNo(flightNo);
        }
        if (StringUtils.isNotBlank(trainNo)) {
          order.setTrainNo(trainNo);
        }

        if (couponIdList.size() > 0) {
          Long couponId = Long.valueOf(couponIdList.get(0));
          if (!couponId.equals(0L)) {
            order.setCouponId(couponId);
          }
          couponIdList.remove(0);
        } else {

          if (typeCoupon.get(String.valueOf(carTypeId)) != null) {
            String str = typeCoupon.get(String.valueOf(carTypeId)).toString();
            if (StringUtils.isNotBlank(couponIdString)) {
              couponIdString += "," + str;
            } else {
              couponIdString = "" + str;
            }
            if (!Long.valueOf(str).equals(0L)) {
              order.setCouponId(Long.valueOf(str));
            }
          }
        }
        order.setGroupId(orderGroup.getId());
        Long employId = null;
        if (employIdList.size() > 0) {
          String employIdStr = employIdList.get(0);
          employIdList.remove(0);
          employId = Long.valueOf(employIdStr);
          order.setEmployId(employId);
        }
        orderService.insert(order);
        PushMessage pushMessage = new PushMessage();
        pushMessage.setAppKey(appKey);
        pushMessage.setTargetId(order.getId());
        if (StringUtils.isNotBlank(orderIds)) {
          orderIds += ",";
        }
        orderIds += order.getId();
        pushMessage.setOrderType("zhuanche");
        if(null!=driverId){
            boolean bool = daijiaApi.findEmployStatus(serverUrl, driverId);// 查询代驾项目司机状态
            if (bool) {
                pushMessage.setMessage("新单派单消息");
                pushMessage.setEmployId(driverId);
                pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER_PAIDAN);
            } else {
                pushMessage.setMessage("新单推送消息");
                pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER);
            }
        }else{
            if (null != employId) {
                boolean bool = daijiaApi.findEmployStatus(serverUrl, employId);// 查询代驾项目司机状态
                if (bool) {
                    pushMessage.setMessage("新单派单消息");
                    pushMessage.setEmployId(employId);
                    pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER_PAIDAN);
                } else {
                    pushMessage.setMessage("新单推送消息");
                    pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER);
                }
            } else {
                pushMessage.setMessage("新单推送消息");
                pushMessage.setPushType(PushMessage.PUSHTYPE_NEWORDER);
            }
        }
        if (null != order.getCouponId() && order.getCouponId() != 0) {
          salesApi.updateV4(order.getCouponId(), 2, appKey);
        }
        try {
          rabbitTemplate.convertAndSend(pushMessage);// 消息加入队列并发送
        } catch (Exception ex) {
          System.err.println("消息发送异常" + ex.getMessage());
        }

        OrderStatus status = new OrderStatus();
        status.setOrderId(order.getId());
        status.setOperator(passengerName);
        status.setOrderNo(order.getOrderNo());
        status.setStatus(0);
        String makeprice="";
        if(order.getIsMakePrice()==1){
          makeprice=",定价订单金额为"+order.getMakePrice();
        }
        if (Order.ORDER_TYPE_PHONE.compareTo(channelName) == 0 
            && StringUtils.isNotBlank(operator)) {
          status.setMemo("管理员【" + operator + "】下单"+makeprice);
        } else {
          status.setMemo("客户【" + order.getPassengerName() + "】下单");
        }
        statusService.insert(status);
        orderList.add(order);
        try {
          //消息推送至队列
          String areaName = "";
          if(null!=serverUrl){
            areaName = daijiaApi.findAreaName(serverUrl, areaId);
          }
          dockingSuperviseApi.pushDdjsMessage(order, passengerPhone, passengerGender, serverDate, startAddress, startLat, startLng,
            type==null?"":type.getName(), endAddress, endLat, endLng,areaId, areaName, memo);
        } catch (Exception e) {
        //   e.printStackTrace();
        }
      }
    }
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("prePay", prePay);
    if (couponMoney != null) {
      map.put("budgetPay", orderPayMoney - couponMoney); // 预算总金额-优惠的总金额
    } else {
      map.put("budgetPay", orderPayMoney);
    }
    if (null != orderGroup.getId()) { // 一组订单
      map.put("orderGroupId", orderGroup.getId());
      map.put("groupType", "group");
    } else { // 一个订单
      map.put("orderGroupId", orderList.get(0).getId());
      map.put("groupType", "order");
    }
    map.put("orderIds", orderIds);
    ResultTransport transport = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);

    transport.setData(map);
    
    
    return transport;
  }

  @Override
  public List<Order> queryByGroupId(OrderQuery orderQuery) {
    return orderService.findByParams(orderQuery);
  }

  @Override
  public DataGrid<Map<String, Object>> findOrdersV4up(OrderQuery orderQuery) {
    List<Map<String, Object>> mapList = new ArrayList<>();

    List<Order> list = orderService.findByParams(orderQuery);

    for (Order order : list) {
      Map<String, Object> map = new HashMap<String, Object>();
      map.put("id", order.getId());
      map.put("orderNo", order.getOrderNo());
      map.put("passengerPhone", order.getPassengerPhone());
      map.put("userPhone", order.getShowPhone());
      map.put("startAddress", order.getStartAddress());
      map.put("startAddressDetail", order.getStartAddressDetail());
      map.put("startLat", order.getStartLat());
      map.put("startLng", order.getStartLng());
      map.put("endAddress", order.getEndAddress());
      map.put("endAddressDetail", order.getEndAddressDetail());
      map.put("endLat", order.getEndLat());
      map.put("endLng", order.getEndLng());
      map.put("status", order.getStatus());
      map.put("serverTime", order.getServerTime().getTime());
      map.put("createdTime", order.getCreated().getTime());
      map.put("review", order.getReview());
      map.put("treatment", order.getTreatment());
      map.put("budgetPay", order.getBudgetPay());
      map.put("startPrice", order.getStartPrice());
      map.put("mileagePrice", order.getMileagePrice());
      map.put("runTimePrice", order.getRunTimePrice());
      map.put("mileage", order.getMileage());
      map.put("runTime", order.getRunTime());
      map.put("realPay", order.getRealPay());
      map.put("companyId", order.getCompanyId());
      map.put("companyName", order.getCompanyName());
      map.put("employId", order.getEmployId());
      map.put("employName", order.getEmployName());// 昵称
      map.put("employPhone", order.getEmployPhone());
      map.put("employNo", order.getEmployNo());// 工号
      map.put("employPhoto", order.getEmployPhoto());
      map.put("employScore", order.getEmployScore());
      map.put("employCompanyId", order.getEmployCompanyId());
      map.put("carNumber", order.getCarNumber());
      map.put("carName", order.getCarName());
      map.put("carTypeName", order.getCarTypeName());
      map.put("orderMemos", order.getOrderMemos());
      map.put("bookStatus",order.getBookStatus());//获得司机的订单类型 1为预约订单
      if (order.getReview() && order.getOrderReview() != null) {
        map.put("orderScore", order.getOrderReview().getScore());
        map.put("orderContent", order.getOrderReview().getContent());
      }
      map.put("memo", order.getMemo());
      map.put("serviceType", order.getServiceType());
      mapList.add(map);
    }
    DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();
    dataGrid.setRows(mapList);

    Long total = orderService.countByParam(orderQuery);

    dataGrid.setTotal(total);
    return dataGrid;
  }

  @Override
  public ResultTransport createMoreV4up(Long passengerId, String passengerName,
      String passengerPhone, Long companyId, String companyName, String channelName,
      Date serverDate, String startAddress, Double startLat, Double startLng, String endAddress,
      Double endLat, Double endLng, Integer travelTime, Double mileage, Long areaId, Long employId,
      String employName, String employPhone, String employPhoto, String employNo,
      Long serviceTypeId, String flightNo, String trainNo, Double budgetPay, Double prestartPrice,
      Double premileagePrice, Double prerunTimePrice, Boolean inBlackList,
      Long rentalCompanyId, String rentalCompanyName, String serverUrl, String appKey,
      Long voiceId, String voiceHttpPath) {
    ResultTransport transport = ResultTransport.getErrorBy(ErrorConstantV4.SUCCESS);
    Order order = new Order();

    order.setPassengerId(passengerId);
    order.setPassengerName(passengerName);
    order.setPassengerPhone(passengerPhone);
    order.setShowPhone(passengerPhone);
    order.setCompanyId(companyId);
    order.setCompanyName(companyName);
    ServiceType serviceType = serviceTypeService.findByServiceTypeId(serviceTypeId, appKey);
    order.setServiceTypeId(serviceTypeId);
    com.ybkj.o2o.zhuanche.entity.Order.ServiceType type2 = Enum.valueOf(
            com.ybkj.o2o.zhuanche.entity.Order.ServiceType.class, serviceType.getName());
    order.setServiceType(type2);
    order.setCarTypeId(serviceType.getCarTypeId());
    Car car = carService.findByEmployId(employId, appKey);
    if (car == null) {
      transport = ResultTransport.getErrorBy(ErrorConstantV4.EMPLOY_HAS_NO_CAR);
      return transport;
    }
    order.setCarId(car.getId());
    order.setCarNumber(car.getCarNumber());
    order.setCarName(car.getCarName());
    order.setChannelName(channelName);
    order.setStartAddress(startAddress);
    order.setStartLat(startLat);
    order.setStartLng(startLng);
    order.setEndAddress(endAddress);
    order.setEndLat(endLat);
    order.setEndLng(endLng);
    order.setServerTime(serverDate);
    order.setBudgetPay(budgetPay);
    order.setPremileage(mileage);
    order.setPretravelTime(travelTime);
    order.setPreStartPrice(prestartPrice);
    order.setPremileagePrice(premileagePrice);
    order.setPrerunTimePrice(prerunTimePrice);
    order.setAreaId(areaId);
    order.setEmployId(employId);
    order.setEmployName(employName);
    order.setEmployPhone(employPhone);
    order.setEmployCompanyId(companyId);
    order.setEmployPhoto(employPhoto);
    order.setEmployNo(employNo);
    order.setAppkey(appKey);
    order.setFlightNo(flightNo);
    order.setTrainNo(trainNo);
    order.setRentalCompanyId(rentalCompanyId);
    order.setRentalCompanyName(rentalCompanyName);
    
    //语音消息
    order.setVoiceId(voiceId);
    order.setVoiceHttpPath(voiceHttpPath);
    
    orderService.addmore(order);
    // 保存下单状态记录
    OrderStatus status = new OrderStatus();
    status.setOrderId(order.getId());
    status.setOperator(employName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(0);
    status.setMemo("服务人员【" + employName + "】补单");

    statusService.insert(status);

    status.setOrderId(order.getId());
    status.setOperator(employName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(1);
    status.setMemo("服务人员补单时系统自动派单");

    statusService.insert(status);
    status.setOrderId(order.getId());
    status.setOperator(employName);
    status.setOrderNo(order.getOrderNo());
    status.setStatus(2);
    status.setMemo("服务人员【" + employName + "】自动接单");

    statusService.insert(status);

    if (inBlackList != null && inBlackList) {

      OrderMemo orderMemo = new OrderMemo();
      orderMemo.setMemo("黑名单客户补单");
      orderMemo.setOperator(employName);
      orderMemo.setOrderId(order.getId());
      orderMemo.setOrderNo(order.getOrderNo());

      orderMemoService.insert(orderMemo);

    }
    PushMessage pushMessage = new PushMessage();
    pushMessage.setAppKey(appKey);
    pushMessage.setTargetId(order.getId());
    pushMessage.setOrderType("zhuanche");
    pushMessage.setMessage("司机补单消息");
    pushMessage.setEmployId(employId);
    pushMessage.setPushType(PushMessage.PUSHTYPE_BUDAN);

    try {
      rabbitTemplate.convertAndSend(pushMessage);// 消息加入队列并发送
    } catch (Exception ex) {
      System.err.println("司机补单消息发送异常" + ex.getMessage());
    }
    transport.setData(order.getId());

    //推送至监管平台
    String areaName = "";
    if(StringUtils.isNotBlank(serverUrl)){
      areaName = daijiaApi.findAreaName(serverUrl, areaId);
      if (null != voiceId) {
        daijiaApi.updateVoiceState(serverUrl,voiceId,order.getId(),order.getOrderNo());
      }
    }
    
    dockingSuperviseApi.pushDdjsMessage(order, passengerPhone, 0, serverDate,
    		startAddress, startLat, startLng, serviceType.getName(), endAddress, endLat, endLng, areaId, areaName, "");
    
    return transport;
  }

  @Override
  public Long countRunningOrder(Long carTypeId, String appKey) {
    return orderService.countRunningOrder(carTypeId, appKey);
  }

  @Override
  public Map<String, Object> findOneV4up(Long id, String appKey) {
    Map<String, Object> map = new HashMap<String, Object>();

    Order order = orderService.findByIdAndAppKey(id, appKey);

    map.put("id", order.getId());
    map.put("orderNo", order.getOrderNo());
    map.put("passengerPhone", order.getPassengerPhone());
    map.put("userPhone", order.getShowPhone());
    map.put("startAddress", order.getStartAddress());
    map.put("startAddressDetail", order.getStartAddressDetail());
    map.put("startLat", order.getStartLat());
    map.put("startLng", order.getStartLng());
    map.put("endAddress", order.getEndAddress());
    map.put("endAddressDetail", order.getEndAddressDetail());
    map.put("endLat", order.getEndLat());
    map.put("endLng", order.getEndLng());
    map.put("status", order.getStatus());
    map.put("serverTime", order.getServerTime().getTime());
    map.put("review", order.getReview());
    map.put("treatment", order.getTreatment());
    map.put("budgetPay", order.getBudgetPay());
    map.put("startPrice", order.getStartPrice());
    map.put("mileagePrice", order.getMileagePrice());
    map.put("runTimePrice", order.getRunTimePrice());
    map.put("mileage", order.getMileage());
    map.put("runTime", order.getRunTime());
    map.put("realPay", order.getRealPay());
    map.put("companyId", order.getCompanyId());
    map.put("companyName", order.getCompanyName());
    map.put("employId", order.getEmployId());
    map.put("employName", order.getEmployName());// 昵称
    map.put("employPhone", order.getEmployPhone());
    map.put("employNo", order.getEmployNo());// 工号
    map.put("employPhoto", order.getEmployPhoto());
    map.put("employScore", order.getEmployScore());
    map.put("employCompanyId", order.getEmployCompanyId());
    map.put("carNumber", order.getCarNumber());
    map.put("carName", order.getCarName());
    map.put("carTypeName", order.getCarTypeName());
    map.put("orderMemos", order.getOrderMemos());
    if (order.getReview() && order.getOrderReview() != null) {
      map.put("orderScore", order.getOrderReview().getScore());
      map.put("orderContent", order.getOrderReview().getContent());
    }

    map.put("memo", order.getMemo());
    map.put("serviceType", order.getServiceType());
    map.put("bookStatus", order.getBookStatus());

    return map;
  }

  @Override
  public Boolean checkExist(Long orderId, String appKey) {
    OrderQuery orderQuery = new OrderQuery();
    orderQuery.setAppKey(appKey);
    orderQuery.setOrderId(orderId);
    Long count = orderService.countByParams(orderQuery);
    if (count > 0) {
      return Boolean.TRUE;
    } else {
      return Boolean.FALSE;
    }
  }

  @Override
  public void cancelByEmployee(Long orderId, String cause, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    Integer status = order.getStatus();
    if (order.getStatus() != 5 && order.getStatus() != 6) {
      if (null != order.getEmployId()) {
        Car car = carService.findByEmployId(order.getEmployId(), appKey);
        if (car != null) {
          car.setStatus(0);
          carService.update(car);
        }
      }
      OrderStatus orderStatus = new OrderStatus();
      orderStatus.setOrderId(orderId);
      orderStatus.setOrderNo(order.getOrderNo());
      orderStatus.setStatus(6);
      orderStatus.setOperator(order.getEmployName());
      order.setStatus(6);
      order.setIsClosed(Boolean.TRUE);
      order.setCancelCause(cause);
      if(status.intValue()>=2){
        orderStatus.setMemo("服务人员" + "【" + order.getEmployName() + "】" + "违约 销单");
      } else {
        orderStatus.setMemo("服务人员" + "【" + order.getEmployName() + "】" + "销单");
      }
      //消息推送至队列
      try {
        if(status.intValue()>=2){
          dockingSuperviseApi.pushDdwyMessage(order, DdwyMessage.DRIVERBREAKER,cause);
        }else{
          dockingSuperviseApi.pushDdcxMessage(order, DdcxMessage.DDCX_DRIVER,cause);
        }
      } catch (Exception e) {
        e.printStackTrace();
      }
      statusService.insert(orderStatus);
      orderService.updateIngoreNull(order);
      chartService.addDayRecord(order);

    }


  }

  @Override
  public DataGrid<Order> queryFinishOrder(OrderQuery orderQuery) {
    DataGrid<Order> dataGrid = new DataGrid<Order>();
    List<Order> list = orderService.queryFinishOrder(orderQuery);
    dataGrid.setRows(list);
    Long total = orderService.countFinishOrder(orderQuery);
    dataGrid.setTotal(total);

    return dataGrid;
  }
  
  @Override
  public DataGrid<Order> selectFinishOrder(OrderQuery orderQuery) {
    DataGrid<Order> dataGrid = new DataGrid<Order>();
    List<Order> list = orderService.selectFinishOrder(orderQuery);
    dataGrid.setRows(list);
    Long total = orderService.countFinishOrderByEmploy(orderQuery);
    dataGrid.setTotal(total);
    
    return dataGrid;
  }

  @Override
  public Boolean prepare(Long orderId, String appKey) {
    Boolean bool = Boolean.FALSE;
    int update = orderService.prepare(orderId, appKey);
    if (update == 1) {
      bool = Boolean.TRUE;
    }
    return bool;
  }

  @Override
  public int autoPaidan(Long orderId, Long employId, String employName, String employPhone,
      Long employCompanyId, String employNo, String employPhoto, Double employScore,
      Long rentalCompanyId, String rentalCompanyName, String appKey) {
    Order order = orderService.findByIdAndAppKey(orderId, appKey);
    order.setUpdated(new Date());

    OrderStatus orderStatus = new OrderStatus();
    orderStatus.setOrderId(order.getId());
    orderStatus.setOrderNo(order.getOrderNo());
    orderStatus.setOperator("系统");
    orderStatus.setStatus(1);
    Car car = carService.findByEmployId(employId, appKey);

    if (car == null) {
      throw new RuntimeException("派单的司机没有车辆");
    }
    order.setCarId(car.getId());
    order.setCarNumber(car.getCarNumber());
    if (null==order.getBookStatus()||order.getBookStatus()!=1) {
    	car.setStatus(1);
        carService.update(car);
	} 
    order.setEmployId(employId);
    order.setEmployName(employName);
    order.setEmployPhone(employPhone);
    order.setEmployCompanyId(employCompanyId);
    order.setEmployNo(employNo);
    if (StringUtils.isNotBlank(employPhoto)) {
      try {
        employPhoto = URLDecoder.decode(employPhoto, "UTF-8");
      } catch (UnsupportedEncodingException ex) {
        ex.printStackTrace();
      }
    }
    order.setEmployPhoto(employPhoto);
    order.setEmployScore(employScore);
    order.setRentalCompanyId(rentalCompanyId);
    order.setRentalCompanyName(rentalCompanyName);
    
    orderStatus.setMemo("【系统】自动派单给服务人员：【" + employName + "】");
    order.setStatus(1);
    statusService.insert(orderStatus);
    return orderService.update(order);
  }


  @Override
  public Long driverOrderDetailCount(OrderQuery orderQuery) {
    return orderService.driverOrderDetailCount(orderQuery);
  }

  @Override
  public Long countRunning(Long passengerId, String appKey) {
    OrderQuery orderQuery = new OrderQuery();
    orderQuery.setPassengerId(passengerId);
    orderQuery.setAppKey(appKey);
    orderQuery.setChannelNameArray("APP预约,微信预约,网站预约");
    orderQuery.setStatusArray("0,1,2,3,4");
    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
    calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
    calendar.set(Calendar.HOUR, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MILLISECOND, 0);
    Date startDate = calendar.getTime();
    orderQuery.setStartTime(startDate.getTime());
    calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
    calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
    calendar.set(Calendar.HOUR, 23);
    calendar.add(Calendar.MINUTE, 59);
    calendar.add(Calendar.SECOND, 59);
    Date endDate = calendar.getTime();
    orderQuery.setEndTime(endDate.getTime());
    
    return orderService.countByParam(orderQuery);
  }
  

  @Override
  public List<Map<String, Object>> countOrderNumByDriver(Long[] driverIds, Date start, Date end, String appKey) {
    driverIds = driverIds==null||driverIds.length==0?null:driverIds;
    return orderService.countOrderNumByDriver(driverIds,start,end,appKey);
  }

  @Override
  public Map<String, Object> countOnDutyByDriver(Long driverId, Date start, Date end) {
    return orderService.countOnDutyByDriver(driverId,start,end);
  }

@Override
public List<Map<String, Object>> countBookDriver(Long zhuanYuyueMax,
		Date zhuanYuyueTime, String appKey) {
	return orderService.countBookDriver(zhuanYuyueMax, zhuanYuyueTime, appKey);
}

@Override
public List<Map<String, Object>> countBusyBookDriver(Date zhuanYuyueTime,
		String appKey) {
	return orderService.countBusyBookDriver(zhuanYuyueTime, appKey);
}

@Override
public List<Map<String, Object>> findDriverBusy(Long zhuanYuyueMax,
		Date zhuanYuyueTime, String appKey, Long employId) {
	return orderService.findDriverBusy(zhuanYuyueMax, zhuanYuyueTime, appKey, employId);
}

@Override
public Integer getTodayBooks(Long employId, Date start, Date end) {
	return orderService.getTodayBooks(employId, start, end);
} 
}
